package com.yc.cloud.openai.portal.utils;

import lombok.SneakyThrows;
import lombok.val;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class AudioUtils {

    public static final String FFMPEG = "ffmpeg";

    @SneakyThrows
    public static boolean pcm2wav(String pcmFilePath, String wavFilePath) {
        List<String> commands = new ArrayList<>();
        commands.add(FFMPEG);
        commands.add("-f");
        commands.add("s16le");
        commands.add("-ar");
        commands.add("16000");
        commands.add("-ac");
        commands.add("1");
        commands.add("-i");
        commands.add(pcmFilePath);
        commands.add(wavFilePath);
        return processCommands(commands);
    }

    public static boolean changeWavSampleRate(String srcPath, String dstPath, int sampleRate) {
        List<String> commands = new ArrayList<>();
        commands.add(FFMPEG);
        commands.add("-y");
        commands.add("-i");
        commands.add(srcPath);
        commands.add("-ar");
        commands.add(String.valueOf(sampleRate));
        commands.add(dstPath);
        return processCommands(commands);
    }

    public static boolean changePcmSampleRate(String srcPath, String dstPath, int srcSampleRate, int dstSampleRate) {
        List<String> commands = new ArrayList<>();
        commands.add(FFMPEG);
        commands.add("-y");
        commands.add("-ar");
        commands.add(String.valueOf(srcSampleRate));
        commands.add("-ac");
        commands.add("1");
        commands.add("-f");
        commands.add("s16le");
        commands.add("-i");
        commands.add(srcPath);
        commands.add("-ar");
        commands.add(String.valueOf(dstSampleRate));
        commands.add("-ac");
        commands.add("1");
        commands.add("-f");
        commands.add("s16le");
        commands.add(dstPath);
        return processCommands(commands);
    }

    public static boolean changePcmSampleRate(String srcPath, String dstPath, int dstSampleRate) {
        List<String> commands = new ArrayList<>();
        commands.add(FFMPEG);
        commands.add("-y");
        commands.add("-i");
        commands.add(srcPath);
        commands.add("-ar");
        commands.add(String.valueOf(dstSampleRate)); // 设置目标采样率为16K
        commands.add("-ac");
        commands.add("1"); // 单声道
        commands.add("-f");
        commands.add("s16le");
        commands.add(dstPath);

        return processCommands(commands);
    }

    private static boolean processCommands(List<String> commands) {
        // System.out.println("commands=" + commands.replaceAll(",", ""););
        val stringBuilder = new StringBuilder();
        for (String command : commands) {
            stringBuilder.append(command).append(" ");
        }
        ProcessBuilder builder = new ProcessBuilder();
        builder.command(commands);
        return processOperation(builder);
    }


    private static boolean processOperation(ProcessBuilder builder) {
        InputStream error = null;
        InputStream is = null;
        try {
            val process = builder.start();
            //process.waitFor();//等待进程执行完毕
            //防止ffmpeg进程塞满缓存造成死锁
            error = process.getErrorStream();
            is = process.getInputStream();
            byte[] b = new byte[1024];
            int readbytes = -1;
            while ((readbytes = error.read(b)) != -1) {
                System.out.println("文件转换错误信息：" + new String(b, 0, readbytes));
                // return  false;
            }
            while ((readbytes = is.read(b)) != -1) {
                System.out.println("文件转换信息：" + new String(b, 0, readbytes));
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
//        finally {
//            try {
//                if (error != null) {
//                    error.close();
//                }
//                if (is != null) {
//                    is.close();
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
        return true;
    }
}
